package com.realshare.frame.component.quartz.service;

import org.quartz.*;
import org.quartz.impl.triggers.CronTriggerImpl;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Date;

import static org.quartz.CronScheduleBuilder.cronSchedule;
import static org.quartz.TriggerBuilder.newTrigger;

/**
 * 单例注入
 * author leisure
 * email 15075107120@139.com
 * create 2018-12-14 下午 5:27
 * modify 2018-12-14 下午 5:27
 **/
@Service
public class QuartzManager {

    private Logger log = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private Scheduler scheduler;

    public boolean isValidExpression(String cronExpression) {
        CronTriggerImpl trigger = new CronTriggerImpl();
        try {
            if (cronExpression == null) {
                log.error("cron表达式未找到！");
                return false;
            }
            trigger.setCronExpression(cronExpression);
            Date date = trigger.computeFirstFireTime(null);
            return date != null && date.after(new Date());
        } catch (Exception e) {
            log.error("cron表达式不正确，异常信息为：" + e.getMessage());
        }
        return false;
    }

    public void scheduleJob(String name, String group, String cron, Class<? extends Job> jobClass) {
        scheduleJob(name, group, name, cron, jobClass, new JobDataMap());
    }

    public void scheduleJob(String name, String group, String description, String cron, Class<? extends Job> jobClass) {
        scheduleJob(name, group, description, cron, jobClass, new JobDataMap());
    }

    public void scheduleJob(String name, String group, String cron, Class<? extends Job> jobClass, JobDataMap jobDataMap) {
        scheduleJob(name, group, name, cron, jobClass, jobDataMap);
    }

    /**
     * 创建任务
     *
     * @param jobClass
     * @param name
     * @param group
     * @param description
     * @param cron
     */
    public void scheduleJob(String name, String group, String description, String cron, Class<? extends Job> jobClass, JobDataMap jobDataMap) {
        try {
            //构建job信息
            JobDetail jobDetail = JobBuilder.newJob(jobClass)
                    .withIdentity(name, group)
                    .withDescription(description)
                    .usingJobData(jobDataMap)
                    .build();
            //cron表达式 表示每隔i秒执行
            CronScheduleBuilder scheduleBuilder = CronScheduleBuilder.cronSchedule(cron)
                    .withMisfireHandlingInstructionDoNothing();

            CronTrigger cronTrigger = TriggerBuilder.newTrigger()
                    .withIdentity(name, group)
                    .withDescription(description)
                    .withSchedule(scheduleBuilder)
                    .startNow().build();

            //如果存在作业则删除作业
            if (scheduler.checkExists(cronTrigger.getKey())) {
                deleteJob(name, group);
            }
            scheduler.scheduleJob(jobDetail, cronTrigger);
        } catch (SchedulerException e) {
            e.printStackTrace();
            log.error("创建定时任务时出错，错误信息为：" + e.getMessage());
        }
    }

    public void triggerJob(String name, String group) {
        log.info("执行单次定时任务【" + name + "】");
        try {
            scheduler.triggerJob(JobKey.jobKey(name, group));
        } catch (SchedulerException e) {
            log.error("Quartz_ERROR[执行单次定时任务失败]@ERROR_MESSAGE==" + e.getMessage());
            e.printStackTrace();
        }
    }

    public void deleteJob(String name, String group) {
        try {
            TriggerKey tk = TriggerKey.triggerKey(name, group);
            scheduler.pauseTrigger(tk);// 停止触发器
            scheduler.unscheduleJob(tk);// 移除触发器
            JobKey jobKey = JobKey.jobKey(name, group);
            scheduler.deleteJob(jobKey);// 删除作业
            log.info("Quartz_[删除作业]@作业名称==" + name + " @作业组==" + group);
        } catch (SchedulerException e) {
            log.error("Quartz_ERROR[删除作业失败]@作业名称==" + name + " @作业组==" + group
                    + " @ERROR_MESSAGE==" + e.getMessage());
            e.printStackTrace();
        }
    }

    public void pauseJob(String name, String group) {
        try {
            JobKey jobKey = JobKey.jobKey(name, group);
            scheduler.pauseJob(jobKey);
            log.info("Quartz_[暂停作业]@作业名称==" + name + " @作业组==" + group);
        } catch (SchedulerException e) {
            log.error("Quartz_ERROR[暂停作业失败]@作业名称==" + name + " @作业组==" + group
                    + " @ERROR_MESSAGE==" + e.getMessage());
            e.printStackTrace();
        }
    }

    public void resumeJob(String name, String group) {
        try {
            JobKey jobKey = JobKey.jobKey(name, group);
            scheduler.resumeJob(jobKey);
            log.info("Quartz_[恢复作业]@作业名称==" + name + " @作业组==" + group);
        } catch (SchedulerException e) {
            log.error("Quartz_ERROR[恢复作业失败]@作业名称==" + name + " @作业组==" + group
                    + " @ERROR_MESSAGE==" + e.getMessage());
            e.printStackTrace();
        }
    }

    public void rescheduleJob(String name, String group, String cronExpression) {
        try {
            TriggerKey tk = TriggerKey.triggerKey(name, group);
            // 构造任务触发器
            Trigger trg = newTrigger().withIdentity(name, group)
                    .withSchedule(cronSchedule(cronExpression)).build();
            scheduler.rescheduleJob(tk, trg);
            log.info("Quartz_[修改作业触发时间]@作业名称==" + name + " @作业组==" + group);
        } catch (SchedulerException e) {
            log.error("Quartz_ERROR[修改作业触发时间失败]@作业名称==" + name + " @作业组=="
                    + group + " @ERROR_MESSAGE==" + e.getMessage());
            e.printStackTrace();
        }
    }

    public void start() {
        try {
            scheduler.start();
            log.info("Quartz_[启动调度器]");
        } catch (SchedulerException e) {
            log.error("Quartz_ERROR[启动调度器失败]@ERROR_MESSAGE==" + e.getMessage());
            e.printStackTrace();
        }
    }

    public void shutdown() {
        try {
            scheduler.shutdown();
            log.info("Quartz_[停止调度器 ]");
        } catch (SchedulerException e) {
            log.error("Quartz_ERROR[停止调度器失败]@ERROR_MESSAGE==" + e.getMessage());
            e.printStackTrace();
        }
    }
}
